#include "my_stdio.h"
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
        

mFILE* mfopen(const char* filename, const char* mode){
    int fd = -1;
    if(strcmp(mode, "r") == 0){
    	fd = open(filename, O_RDONLY);
    }
    else if(strcmp(mode, "w") == 0){
	fd = open(filename, O_CREAT|O_WRONLY|O_TRUNC, 0666);
    }
    else if(strcmp(mode, "a") == 0){
	fd = open(filename, O_CREAT|O_WRONLY|O_APPEND, 0666);
    }
    
    //文件打开失败
    if(fd < 0) return NULL;
    
    //为文件对象开辟空间
    mFILE* mf = (mFILE*)malloc(sizeof(mFILE));

    //开辟空间失败
    if(mf == NULL){
	close(fd);
	return NULL;
    }
    
    //打开成功
    mf->fileno = fd;
    mf->flush_way = FLUSH_LINE;
    mf->size = 0;
    mf->capacity = SIZE;

    return mf;
}

int mfflush(mFILE* stream){
    if(stream->size > 0){
        //从用户级缓冲区刷新到内核级缓冲区
        write(stream->fileno, stream->outbuffer, stream->size);

        //强制刷新内核级缓冲区的数据到存储设备
        fsync(stream->fileno);
        stream->size = 0;
    }

    return 0;
}

int mfwrite(const void* ptr, int num, mFILE* stream){
    //1.写入的本质就是拷贝，从已有数据的下一个位置开始填充
    memcpy(stream->outbuffer+stream->size, ptr, num);
    stream->size += num;

    //2.检测是否需要刷新
    if(stream->flush_way == FLUSH_LINE && stream->size > 0 && stream->outbuffer[stream->size-1] == '\n'){
        mfflush(stream);
    }

    return num;
}


int mfclose(mFILE* stream){
    //在关闭时，如果缓冲区里有数据，就刷新缓冲区
    if(stream->size > 0){
        mfflush(stream);
        stream->size = 0;
    }
    close(stream->fileno);
    return 0;
}
